package org.kingtop.mybatis.util;

import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.ExecutorException;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.Configuration;

/**
 * 主键生成器的工具类，主要是为参数设置值<br>
 * 目前用于RedisKeyGenerator、IdWorkerKeyGenerator
 * @author 陈金波
 * @date   2018年1月16日 下午8:19:46    
 * @Copyright: 2018 chen jinbo. All rights reserved.
 */
public class KeyGeneratorUtil {

	/**
	 * 为插入插入主键
	 * @author 陈金波  
	 * @date   2018年1月10日 下午9:48:24  
	 * @param executor
	 * @param ms
	 * @param stmt
	 * @param parameters
	 * @return void
	 */
	public static void processBatch(Executor executor, MappedStatement ms, Statement stmt, Collection<Object> parameters, Long value) {
		try {
			final Configuration configuration = ms.getConfiguration();
			final String[] keyProperties = ms.getKeyProperties();
			if (keyProperties != null) {
				for (Object parameter : parameters) {
					final MetaObject metaParam = configuration.newMetaObject(parameter);
					populateKeys(value, metaParam, keyProperties);
				}
			}
		} catch (Exception e) {
			throw new ExecutorException(
					"Error getting generated key or setting result to parameter object. Cause: " + e, e);
		}
	}

	/**
	 * 因为parameter可能是个list，批量插入的时候
	 * 
	 * @author 陈金波
	 * @date 2018年1月10日 下午7:59:46
	 * @param parameter
	 * @return
	 * @return Collection<Object>
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static Collection<Object> getParameters(Object parameter) {
		Collection<Object> parameters = null;
		if (parameter instanceof Collection) {
			parameters = (Collection) parameter;
		} else if (parameter instanceof Map) {
			Map parameterMap = (Map) parameter;
			if (parameterMap.containsKey("collection")) {
				parameters = (Collection) parameterMap.get("collection");
			} else if (parameterMap.containsKey("list")) {
				parameters = (List) parameterMap.get("list");
			} else if (parameterMap.containsKey("array")) {
				parameters = Arrays.asList((Object[]) parameterMap.get("array"));
			}
		}
		if (parameters == null) {
			parameters = new ArrayList<Object>();
			parameters.add(parameter);
		}
		return parameters;
	}

	public static void populateKeys(Long value, MetaObject metaParam, String[] keyProperties) throws SQLException {
		for (int i = 0; i < keyProperties.length; i++) {
			String property = keyProperties[i];
			metaParam.setValue(property, value);
		}
	}
	
}
